﻿/* Includes: */
#include "GraphEngine.h"

/** Общее количество элементов меню. */
#define MENU_ITEMS_COUNT 3

/** Расстояние между строками элементов главного меню. */
#define MENU_ITEM_SPACE 40

/** Вертикальное значение позиции списка элементов главного меню игры. */
#define MENU_ITEMS_VER_POS 150

/** Перечислитель идентификаторов для элементов главного меню. */
enum MenuItemId {
    MenuItemIdNewGame,  //!< Элемент для запуска новой игры.
    MenuItemIdRecords,  //!< Элемент отображения списка рекордов.
    MenuItemIdSettings  //!< Элемент настроек программы.
};

/** Глобальный список элементов главного меню. */
const char* g_menuItemNames[MENU_ITEMS_COUNT] = {
    "New Game",
    "Records",
    "Settings"
};

static GrSceneAbstract* createItemScene( int itemIdx )
{
    CCDirector::sharedDirector()->purgeCachedData();

    GrSceneAbstract* scene = NULL;

    switch ( itemIdx ) {
        case MenuItemIdNewGame:
            scene = GE_GET_LOADING_SCREEN_SCENE;
            break;
        case MenuItemIdRecords:
            scene = GE_GET_RECORDS_SCREEN_SCENE;
            break;
        case MenuItemIdSettings:
            scene = GE_GET_SETTINGS_SCREEN_SCENE;
            break;
        default:
            break;
    }

    return scene;
}

GrMainMenuLayer::GrMainMenuLayer()
{
    /* Получаем размер текущего окна, для последующего использования */
    CCSize s = CCDirector::sharedDirector()->getWinSize();

    /* Добавляем название игры. */
    CCLabelTTF* label = CCLabelTTF::labelWithString( "BROOK", "Arial", 32);
    label->setColor( ccc3( 250, 255, 117 ) );
    label->setPosition( ccp( s.width / 2, s.height - 100 ) );
    
    this->addChild( label, 0 );

    /* Добавляем кнопку выхода из игры. */
    CCMenuItemImage *pExitItem = CCMenuItemImage::itemFromNormalImage( 
                                    "CloseNormal.png", "CloseSelected.png", 
                                    this, menu_selector( GrMainMenuLayer::exitCallback ) );
    CCMenu* pMenu = CCMenu::menuWithItems( pExitItem, NULL);

    pMenu->setPosition( CCPointZero );
    pExitItem->setPosition( ccp( s.width - 30, /* s.height -*/ 30 ) );

    /* Добавляем список элементов меню. */
    CCMenu* itemsMenu = CCMenu::menuWithItems( NULL );
    for ( int i = 0; i < MENU_ITEMS_COUNT; ++i )
    {
        CCLabelTTF* label = CCLabelTTF::labelWithString( g_menuItemNames[i], "Arial", 24 );
        CCMenuItemLabel* pMenuItem = CCMenuItemLabel::itemWithLabel( label, this, 
                                        menu_selector( GrMainMenuLayer::menuCallback ) );

        itemsMenu->addChild( pMenuItem, i + 10000 );
        pMenuItem->setPosition( ccp(  s.width / 2, 
                                    ( s.height - MENU_ITEMS_VER_POS - ( i + 1 ) * MENU_ITEM_SPACE ) ) );
    }

    itemsMenu->setContentSize( CCSizeMake(  s.width, 
                                          ( MENU_ITEMS_COUNT + 1) * ( MENU_ITEM_SPACE ) ) );
    itemsMenu->setPosition( CCPointZero );
    this->addChild( itemsMenu, 1 );

    setIsTouchEnabled( true );

    this->addChild( pMenu, 2 );
}

GrMainMenuLayer::~GrMainMenuLayer()
{
}

void GrMainMenuLayer::menuCallback( CCObject * pSender )
{
    /* Получаем индекс выбранного элемента меню. */
    CCMenuItem* menuItem = (CCMenuItem *)( pSender );
    int index = menuItem->getZOrder() - 10000;

    /* Cоздадим сцену и запускаем ее. */ 
    GrSceneAbstract* pScene = createItemScene( index );
    if ( pScene ) {
        pScene->runScene();
        pScene->release();
    }
}

void GrMainMenuLayer::exitCallback(CCObject * pSender)
{
    CCDirector::sharedDirector()->end();
#if ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
	exit( 0 );
#endif
}

GrSplashScreenLayer::GrSplashScreenLayer()
{
    /* Получаем размер текущего окна, для последующего использования */
    CCSize s = CCDirector::sharedDirector()->getWinSize();

    /* Добавляем название игры на заставку. */
    /*CCLabelTTF* label = CCLabelTTF::labelWithString( "BROOK", "Arial", 32);
    label->setColor( ccc3( 250, 255, 117 ) );
    label->setPosition( ccp( s.width / 2, s.height - 100 ) );
    
    this->addChild( label, 1 );*/

    /* Добавляем картинку заставки. */
    CCSprite* sprite = CCSprite::spriteWithFile( "Splash.png" );

    /* Помещаем картинку заставки в центр окна. */
    sprite->setPosition( ccp( s.width/2, s.height/2 ) );

    // add the sprite as a child to this layer
    this->addChild( sprite, 0 );

    /* Устанавливаем таймер на 1 сек. показа заставки. */
    scheduleUpdate();
    schedule( schedule_selector( GrSplashScreenLayer::_timerCallback ), 1.0f );
}

GrSplashScreenLayer::~GrSplashScreenLayer()
{
}

void GrSplashScreenLayer::_timerCallback( ccTime )
{
    GE_SHOW_MAIN_MENU;
}

GrLoadingScreenLayer::GrLoadingScreenLayer()
{
    /* Получаем размер текущего окна, для последующего использования */
    CCSize s = CCDirector::sharedDirector()->getWinSize();

    /* Добавляем сообщение о процессе загрузки игры. */
    CCLabelTTF* label = CCLabelTTF::labelWithString( "LOADING...", "Arial", 32);
    label->setColor( ccc3( 250, 255, 117 ) );
    label->setPosition( ccp( s.width / 2, 100 ) );
    
    this->addChild( label, 1 );

    /* Добавляем картинку заставки. */
	CCSprite* sprite = CCSprite::spriteWithFile( "Splash.png" );

    /* Помещаем картинку заставки в центр окна. */
    sprite->setPosition( ccp( s.width/2, s.height/2 ) );

    // add the sprite as a child to this layer
    this->addChild( sprite, 0 );

    /* Устанавливаем таймер на 1 сек. показа процесса загрузки игры. */
    scheduleUpdate();
    schedule( schedule_selector( GrLoadingScreenLayer::_timerCallback ), 2.0f );
}

GrLoadingScreenLayer::~GrLoadingScreenLayer()
{
}

void GrLoadingScreenLayer::_timerCallback( ccTime )
{
    GE_SHOW_GAME_SCENE;
}

void GrLoadingScreenScene::runScene()
{
    CCLayer* layer = new GrLoadingScreenLayer();
    this->addChild( layer );
    layer->release();

    CCDirector::sharedDirector()->replaceScene( 
                    GE_MAKE_SCENE_TRANSACTION( SCENE_TRANSITION_DURATION, this ) );
}

GrRecordsScreenLayer::GrRecordsScreenLayer()
{
    /* Получаем размер текущего окна, для последующего использования */
    CCSize s = CCDirector::sharedDirector()->getWinSize();

    /* Добавляем название сцены игры. */
    CCLabelTTF* label = CCLabelTTF::labelWithString( "Game Records List", "Arial", 32);
    label->setColor( ccc3( 250, 255, 117 ) );
    label->setPosition( ccp( s.width / 2, s.height - 50 ) );
    
    this->addChild( label, 1 );

    /* Добавляем список записей рекордов. */
    for ( int i = 0; i < 10; ++i ) {
        char buf[256] = "";

        sprintf( buf, "%d. ------ ", i + 1 );

        CCLabelTTF* recLabel = CCLabelTTF::labelWithString( buf, "Arial", 24 );

        recLabel->setPosition( ccp(  s.width / 2 - 100, 
                                   ( s.height - 100 - ( i + 1 ) * 30 ) ) );
        this->addChild( recLabel, i + 10000 );
    }
}

GrRecordsScreenLayer::~GrRecordsScreenLayer()
{
}

GrRecordsScreenScene::GrRecordsScreenScene( bool showMenuBtn )
    : GrSceneAbstract( showMenuBtn )
{
}

void GrRecordsScreenScene::runScene()
{
    CCLayer* layer = new GrRecordsScreenLayer();
    this->addChild( layer );
    layer->release();

    CCDirector::sharedDirector()->replaceScene( 
                    GE_MAKE_SCENE_TRANSACTION( SCENE_TRANSITION_DURATION, this ) );
}

/** Расстояние между строками элементов меню настроек. */
#define SETTINGS_MENU_ITEM_SPACE 40

/** Вертикальное значение позиции списка элементов меню настроек. */
#define SETTINGS_MENU_ITEMS_VER_POS 150

const char* g_settingItemsNames[SETTINGS_MENU_ITEMS_COUNT] = {
    "Sound",
    "Music"
};

GrSettingsScreenLayer::GrSettingsScreenLayer()
{
    /* Получаем размер текущего окна, для последующего использования */
    CCSize s = CCDirector::sharedDirector()->getWinSize();

    /* Добавляем название сцены игры. */
    CCLabelTTF* label = CCLabelTTF::labelWithString( "Settings", "Arial", 32);
    label->setColor( ccc3( 250, 255, 117 ) );
    label->setPosition( ccp( s.width / 2, s.height - 50 ) );
    
    this->addChild( label, 0 );

    memset( p_settingVal, 0, sizeof( p_settingVal ) );
    
    /* Добавляем список элементов настроек. */
    CCMenu* menu = CCMenu::menuWithItems( NULL );
    for ( int i = 0; i < SETTINGS_MENU_ITEMS_COUNT; ++i )
    {
        CCLabelTTF* itemTitle = CCLabelTTF::labelWithString( g_settingItemsNames[i], "Arial", 24 );
        itemTitle->setPosition( ccp(  s.width / 2 - 50, 
                                   ( s.height - SETTINGS_MENU_ITEMS_VER_POS - 
                                     ( i + 1 ) * SETTINGS_MENU_ITEM_SPACE ) ) );
        this->addChild( itemTitle, i + 10000 );
        CCLabelTTF* menuLabel = NULL;
        if ( p_settingVal[i] > 0 ) {
            menuLabel = CCLabelTTF::labelWithString( "On", "Arial", 24 );
        } else {
            menuLabel = CCLabelTTF::labelWithString( "Off", "Arial", 24 );
        }

        CCMenuItemLabel* menuItem = CCMenuItemLabel::itemWithLabel( menuLabel, this, 
                                        menu_selector( GrSettingsScreenLayer::itemSelectCallback ) );

        menu->addChild( menuItem, i + 10000 );
        menuItem->setPosition( ccp(  s.width / 2 + 100, 
                                   ( s.height - SETTINGS_MENU_ITEMS_VER_POS - 
                                     ( i + 1 ) * SETTINGS_MENU_ITEM_SPACE ) ) );
    }

    menu->setContentSize( CCSizeMake(  s.width, 
                                     ( SETTINGS_MENU_ITEMS_COUNT + 1) * ( SETTINGS_MENU_ITEM_SPACE ) ) );
    menu->setPosition( CCPointZero );
    this->addChild( menu, 1 );

    setIsTouchEnabled( true );
}

GrSettingsScreenLayer::~GrSettingsScreenLayer()
{
}

void GrSettingsScreenLayer::itemSelectCallback( CCObject* pSender )
{
    /* Получаем индекс выбранного элемента меню. */
    CCMenuItemLabel* menuItem = (CCMenuItemLabel *)( pSender );
    int index = menuItem->getZOrder() - 10000; 
    char val = p_settingVal[index];
    CCLabelTTF* menuLabel = NULL;
    if ( val > 0 ) {
        val = 0;
        menuLabel = CCLabelTTF::labelWithString( "Off", "Arial", 24 );
    } else {
        val = 1;
        menuLabel = CCLabelTTF::labelWithString( "On", "Arial", 24 );
    }
    menuItem->setLabel( menuLabel );
    p_settingVal[index] = val;
}

GrSettingsScreenScene::GrSettingsScreenScene( bool showMenuBtn )
    : GrSceneAbstract( showMenuBtn )
{
}

void GrSettingsScreenScene::runScene()
{
    CCLayer* layer = new GrSettingsScreenLayer();
    this->addChild( layer );
    layer->release();

    CCDirector::sharedDirector()->replaceScene( 
                    GE_MAKE_SCENE_TRANSACTION( SCENE_TRANSITION_DURATION, this ) );
}
